// `include "./datapath/im.v"
// `include "./datapath/pc.v"
// `include "./datapath/npc.v"
// `include "./datapath/reg.v"
// `include "./datapath/alu.v"
// `include "./control/alu_ctr.v"
// `include "./control/mux.v"
// `include "./datapath/dm.v"
// `include "./datapath/ext.v"
`include "./mips/datapath/im.v"
`include "./mips/datapath/pc.v"
`include "./mips/datapath/npc.v"
`include "./mips/datapath/reg.v"
`include "./mips/datapath/alu.v"
`include "./mips/control/alu_ctr.v"
`include "./mips/control/mux.v"
`include "./mips/datapath/dm.v"
`include "./mips/datapath/ext.v"
module Datapath(RegDst, Branch, MemtoReg, AluOp, MemWrite, AluSrc, RegWrite, Jump, Sign,clk, rst, instr);

    input RegDst;      // destinate register
    input Branch;      // branch
    input MemtoReg;    // data's source written into reg 
    input AluSrc;      // alu's 2nd data's source
    input[3:0] AluOp;       // alu signal
    input MemWrite;    // dm write enable
    input RegWrite;    // regfile write enable
    input Jump;        // jump
    input Sign;
    input clk;         // clock
    input rst;         // reset
    output [31:0]  instr;       // im output instruction
    wire   [31:0]  pc;
    wire   [31:0]  npc;
    wire   [31:0]  instr;       // 32-bit instruction
    wire           zero;        // alu count, about beq
    wire   [ 4:0]  des_reg;      // destinate register
    wire   [31:0]  writedata;   // data written into regfile from mux3
    wire   [31:0]  rd1, rd2;    // read from $rs and $rt
    wire   [31:0]  b;           // second data into alu   
    wire   [31:0]  result;      // alu counts result
    wire   [ 3:0]  AluCtrl;     // control the operation of alu
    wire   [31:0]  dmout;       // data output by dm
    wire [31:0] ext;
    Pc pc_(npc, clk, rst, pc);
    
    Npc npc_(pc, instr[25:0], Branch, zero, Jump, npc);

    im_4k im(pc[11:0], instr);    
    
    MuxReg mux_reg(instr[20:16], instr[15:11], RegDst, des_reg);
    Reg regfile(instr[25:21], instr[20:16], des_reg, RegWrite,writedata, clk,rst,rd1, rd2);
    
    Extender extender(instr[15:0],Sign,ext);
    MuxAlu mux_alu(rd2, ext, AluSrc, b);
    AluControl alu_ctr(AluOp, instr[5:0], AluCtrl);
    Alu alu( AluCtrl,rd1, b, zero, result);

    dm_4k dm(result[11:2], rd2, MemWrite, clk, dmout);
    MuxDm mux_dm(dmout, result, MemtoReg, writedata);
    
endmodule